<script setup lang="ts">
import commonUtil, {EAction, ECode, iconFontAddress, PagePath} from "@/util/commonUtil";
import {router} from "@/router";
import {computed, ref, watch} from "vue";
import {useAppConfigStore} from "@/store/system/appConfigStore";
import {message} from "ant-design-vue";
import {userConfigStore} from "@/store/user/userConfigStore";
import Praise from "@/components/praise/index.vue";
import xss from "xss";
import {timeAgoConvert} from "@/util/timeUtil";
import {v4 as uuidV4} from 'uuid';
import {loginConfigStore} from "@/store/user/loginConfigStore";
import {createFromIconfontCN} from "@ant-design/icons-vue";
import {useSysEventStore} from "@/store/system/SysEventStore";
import {addComment} from "@/api/comment/comment";
import CommentBox from "../commentBox/index.vue"
import Report from "@/components/report/index.vue"
import {useSystemDictStore} from "@/store/system/systemDictStore";
import _ from "lodash";

const props = defineProps({
  // 父级组件传过来的评论列表
  comments: {
    type: Array<any>,
    default: () => []
  },
  userInfos: {
    type: Object
  },
  // 评论主体信息
  commentInfo: {
    type: Object
  },
  // 递归组件的嵌套层级，递归了1层、2层、3层、4层、5层，在最后一层可以禁止回复，拒绝无休止的评论
  level: {
    type: Number,
    default: 1,
  },
  marginLeft: {
    type: Number,
    default: 0,
  },
  // 控制最大评论层级
  maxReplyLevel: {
    type: Number,
    default: 5,
  },
  // 作者UID
  authorUid: {
    type: String,
    default: '',
  }
});
watch(() => props.comments, () => {
  commentList.value = props.comments
})

// 引入阿里图标库
const IconFont = createFromIconfontCN({
  scriptUrl: iconFontAddress,
});
const commentList = ref<any>(props.comments)
// xss白名单配置
const options = ref({
  whiteList: {
    div: ['class'],
    br: ['class'],
    a: ['href', 'title', 'target', 'style', 'class'],
    span: ['class', 'style'],
    h1: ['class'],
    h2: ['class'],
    h3: ['class'],
    h4: ['class'],
    ol: ['start'],
    pre: [],
    code: ['class'],
    p: ['class'],
    blockquote: ['class'],
    ul: ['class'],
    li: ['class'],
    img: ['class', 'src', 'alt', 'style'],
    hr: [],
    video: ['class', 'src', 'controls'],
    source: ['src', 'type']
  }
})
const componentShowMap = computed(() => useAppConfigStore().componentShowMap)
const toInfo = ref<any>({
  uid: "",
  commentUid: ""
})
const reportInfo = ref<any>({})
const dialogReportVisible = ref<boolean>(false)
const userInfo = ref<any>({})
const userTagDictList: any = computed(() => useSystemDictStore().SysUserTag)

function getTagName(tagId: string) {
  if (_.isEmpty(userTagDictList.value)) {
    return;
  }
  return userTagDictList.value.find((item: any) => item.dictValue == tagId)?.dictLabel
}

function getUserCenter(user: any) {
  let routeData = router.resolve({
    path: PagePath.UserCenterPath,
    query: {userUid: user.uid}
  });
  window.open(routeData.href, '_blank');
}

function replyTo(item: any) {
  if (!validLogin()) {
    message.warning("登录后才能回复评论哦~")
    loginConfigStore().setLoginMessage(uuidV4())
    return
  }
  let userUid = item.userUid;
  toInfo.value.commentUid = item.uid
  toInfo.value.uid = userUid
}

// 校验是否登录
function validLogin() {
  let userInfo: any = userConfigStore().userInfo
  return userInfo.userName != undefined;
}

function report(item: any) {
  let report: any = {}
  report.reportType = "comment" // 评论
  report.reportUserUid = item.userUid // 被举报人id
  report.reportContentUid = item.uid
  report.reportContent = item.content
  reportInfo.value = report
  dialogReportVisible.value = true
}

function convertContent(comment: any) {
  let toUser = comment.toUser
  let content = comment.content
  if (toUser && comment.toUid != comment.firstCommentUid) {
    let userCenterUrl = PagePath.UserCenterPath + "?userUid=" + toUser.uid
    content = "<span><a class='atUserLine text-orange-500' href='" + userCenterUrl + "' target='_blank'>@" + toUser.nickName + "</a></span>" + content;
  }
  content = commonUtil.replaceMinImg(content)
  if (document.body.clientWidth > 1000) {
    content = commonUtil.replaceMinIframe(content)
  }
  return content
}

function showCancelCallBack() {
  toInfo.value.commentUid = ""
}

async function submitBox(e: any) {
  let params: any = {};
  params.source = e.source;
  params.userUid = e.userUid;
  params.content = e.content;
  params.blogUid = e.blogUid;
  params.toUid = e.toCommentUid;
  params.toUserUid = e.toUserUid;
  await addComment(params).then((response: any) => {
    if (response.code === ECode.SUCCESS) {
      let commentData = response.data
      toInfo.value.commentUid = ""
      let comments = useSysEventStore().commentList;
      commentData.user = userInfo.value;
      // 设置回复为空
      commentData.replyList = [];
      commentData.user = userConfigStore().userInfo
      updateCommentList(comments, commentData.toUid, commentData)
      useSysEventStore().setCommentList(comments)
      // 刷新评论列表
      useSysEventStore().setCommentMessage(uuidV4())
      message.success("评论成功！");
      // 发送评论的领域事件
      let event = {
        "type": "action",
        "action": EAction.Comment,
        "resourceUid": e.blogUid,
        "resourceType": "BLOG",
        "time": new Date(),
      }
      useSysEventStore().setDomainEventMessage(event)
    } else {
      message.error(response.message)
    }
  })
}

// 追加内容
function updateCommentList(commentList: any, uid: any, targetComment: any) {
  if (commentList == undefined || commentList.length <= 0) {
    return;
  }
  for (let item of commentList) {
    let replyList = item.replyList;
    if (replyList == null) {
      replyList = []
    }
    if (item.uid == uid) {
      replyList.unshift(targetComment);
      item.replyList = replyList
      return;
    }
    for (let reply of replyList) {
      if (reply.uid == uid) {
        replyList.unshift(targetComment);
        item.replyList = replyList
        return;
      }
    }
  }
}

function beforeClose(e: boolean) {
  dialogReportVisible.value = e
}
</script>

<template>
  <div class="commentReply">
    <template v-for="(item,index) in comments">
      <a-comment>
        <template #avatar>
          <div class="commentAvatar relative" @click="getUserCenter(item.user)">
            <a-avatar v-if="item.user.photoUrl" size="large"
                      class="h-10 w-10 flex items-center justify-center avatar-item"
                      :src="item.user.photoUrl"
                      style="border: var(--vip-border)"/>
            <a-avatar v-else size="large" class="h-10 w-10 flex items-center justify-center avatar-item"
                      style="border: var(--vip-border)">
              {{ item.user.nickName.slice(0, 1) }}
            </a-avatar>
            <sub class="badgeSup h-4 w-4 absolute bottom-1 right-0" v-if="item.user.userTag > 0">
              <img src="@/assets/vip/vip.svg" class="h-full w-full" alt="vipBadge">
            </sub>
          </div>
          <div class="h-full w-full flex justify-center items-center">
            <i class="borderLink not-italic h-full w-[1px]"></i>
          </div>
        </template>
        <template #author>
          <span class="font-semibold text-[14px] cursor-pointer">{{ item.user.nickName }}</span>
        </template>
        <template #actions>
          <span v-if="level < maxReplyLevel" @click="replyTo(item)">回复</span>
          <span v-if="componentShowMap.showUserReport" class="" @click="report(item)">举报</span>
          <span>
        <Praise :bizUid="item.uid" :resourceType="'5'"
                :isPraiseValue="item.praiseInfo?item.praiseInfo.isPraise:false"
                :isTreadValue="item.praiseInfo?item.praiseInfo.isPraise:false"
                :praiseCountValue="item.praiseInfo?item.praiseInfo.praiseCount:0"
                :treadCountValue="item.praiseInfo?item.praiseInfo.treadCount:0"
        ></Praise>
      </span>
        </template>
        <template #content>
          <span class="flex flex-col lg:flex-row lg:inline-flex gap-2 overflow-hidden" v-highlight
                v-html="xss(convertContent(item), options)"></span>
        </template>
        <template #datetime>
          <span class="userTag">
            <a-tag color="orange">
              <template #icon>
                <IconFont type="icon-huibiao"/>
              </template>
              {{ getTagName(item.user.userTag) }}
            </a-tag>
          </span>
          <a-tag class="lv mr-2" color="purple" v-if="item.user.userLevel" :class="'lv'+ item.user.userLevel">
            <template #icon>
              <IconFont type="icon-huibiao"/>
            </template>
            Lv{{ item.user.userLevel }}
          </a-tag>
          <a-tag class="mr-2" v-if="authorUid == item.user.uid" color="magenta">作者</a-tag>
          <span v-if="item.user.userIpPossession" class="mr-2">IP属地:<i
              class="not-italic">{{ item.user.userIpPossession }}</i></span>
          <span class="mr-2">{{ timeAgoConvert(item.createTime) }}</span>
          <a-tag v-if="item.isTop == 1" color="red">置顶</a-tag>
          <span>{{ index + 1 }}楼</span>
        </template>
      </a-comment>
      <div class="replyCommentChildren" v-if="toInfo.commentUid === item.uid">
        <CommentBox
            class="replyCommentBox"
            :toInfo="toInfo"
            :userInfo="userInfo"
            :id="item.uid"
            @submit-box="submitBox"
            @showCancel="showCancelCallBack"
            :commentInfo="commentInfo">
        </CommentBox>
      </div>
    </template>
    <Report v-if="dialogReportVisible" :visible="dialogReportVisible" :reportInfo="reportInfo"
            @beforeClose="beforeClose"/>
  </div>
</template>

<style scoped lang="less">
:deep(.ant-tag >.anticon+span) {
  margin-inline-start: 0;
}

.borderLink {
  border-left: 1px dashed hsl(var(--font-color) / .2);
}

:deep(.ant-comment):last-child .borderLink {
  border-left: none;
}
</style>
